package com.ruoyi.common.utils.sign;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
 * @author Administrator
 * @description 拓安信 签名工具类
 * @data 2025/9/24 13:44
 */
@Component
public class TAXSignatureUtil {

    private final ObjectMapper objectMapper;

    public TAXSignatureUtil(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    /**
     * 生成签名
     */
    public String generateSignature(String appId, String secretKey, long timestamp,
                                    Map<String, Object> params) {
        try {
            // 对参数进行自然排序
            String sortedParams = sortParams(params);

            // 拼接签名字符串
            String signString = appId + sortedParams + secretKey + timestamp;

            // MD5加密
            return DigestUtils.md5Hex(signString).toLowerCase();
        } catch (Exception e) {
            throw new RuntimeException("签名生成失败", e);
        }
    }

    /**
     * 参数自然排序
     */
    private String sortParams(Map<String, Object> params) {
        if (params == null || params.isEmpty()) {
            return "";
        }

        List<String> paramList = new ArrayList<>();
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            String value;
            if (entry.getValue() instanceof String) {
                value = (String) entry.getValue();
            } else {
                // 将对象转换为JSON字符串并去除空格换行
                try {
                    value = objectMapper.writeValueAsString(entry.getValue())
                            .replaceAll("\\s+", "");
                } catch (Exception e) {
                    value = entry.getValue().toString();
                }
            }
            paramList.add(entry.getKey() + "=" + value);
        }

        // 自然排序
        Collections.sort(paramList);

        return String.join(",", paramList);
    }

    /**
     * 验证时间戳有效性（与服务器时间相差不超过1小时）
     */
    public boolean validateTimestamp(long clientTimestamp) {
        long serverTimestamp = System.currentTimeMillis();
        long diff = Math.abs(serverTimestamp - clientTimestamp);
        return diff <= 3600000L; // 1小时
    }
}
